home *** CD-ROM | disk | FTP | other *** search
- //#define DEBUG
-
- #include "MP.h"
- #include <debug.h>
- #include <exec/lists.h>
-
- extern struct MPSem *MPSem;
-
- // LockPubScreenList
- extern struct List * __asm (*OldLockPubScreenList)(register __a6 struct Library *);
- extern void __asm (*OldUnlockPubScreenList)(register __a6 struct Library *);
-
- struct List PubScreenList;
- LONG PubListNest=0; // If Zero then Init
-
- struct PubScreenNode BuggyPSN;
-
- struct List * __saveds __asm NewLockPubScreenList(register __a6 struct IntuitionBase *IBase)
- {
- struct PubScreenNode *psn,*npsn;
- struct DefaultNode *dnode;
- struct List *list;
- char tnamebuffer[52];
- char *tname;
-
- tname=SetupTaskName(tnamebuffer," in NewLockPubScreenList()",50);
-
- DEBUG_CODE(
- DKP("LockPubScreenList()\n");
- )
-
- ObtainSemaphoreShared(&MPSem->ListSem);
- ObtainSemaphore(&MPSem->NodeSem);
-
- list=OldLockPubScreenList((struct Library *)IBase);
-
- /* Clone Old PS list */
-
- if(PubListNest==0)
- {
- // The OS nests calls to LockPubScreenList()/UnlockPubScreenList() only create the list when PubListNest==0
- NewList(&PubScreenList);
-
- psn=(struct PubScreenNode *)list->lh_Head;
- while(psn->psn_Node.ln_Succ)
- {
- if(npsn=AllocVec(sizeof(*npsn),MEMF_PUBLIC))
- {
- *npsn=*psn;
- AddTail(&PubScreenList,(struct Node *)npsn);
- }
-
- psn=(struct PubScreenNode *)psn->psn_Node.ln_Succ;
- }
-
- /* Make PSNodes for MP's pubscreens */
-
- dnode=(struct DefaultNode *)MPSem->PromotionList[PL_PUBLICSCREENS].lh_Head;
-
- while(dnode->Def_Node.ln_Succ)
- {
- if(!FindName(&PubScreenList,dnode->Def_Node.ln_Name))
- { /* Avoid Duplicates */
- if(npsn=AllocVec(sizeof(*npsn),MEMF_PUBLIC|MEMF_CLEAR))
- {
- npsn->psn_Node.ln_Name=dnode->Def_Node.ln_Name; // Safe to reference name since lists are protected till UnlockPubScreenList()
- AddTail(&PubScreenList,(struct Node *)npsn);
- }
- }
- dnode=(struct DefaultNode *)dnode->Def_Node.ln_Succ;
- }
- }
- else
- {
- // nested
- }
-
-
- /*
- {
- LONG *l,q;
-
- l=0;
-
- *l=0;
- }*/
-
- PubListNest++; // Some dumb apps call LockPubScreen() inside LockPubScreenList()/UnlockPubScreenList()
-
- SetTaskName(tname);
-
- return(&PubScreenList);
- }
-
- void __saveds __asm NewUnlockPubScreenList(register __a6 struct IntuitionBase *IBase)
- {
- struct PubScreenNode *psn;
- char tnamebuffer[52];
- char *tname;
-
- tname=SetupTaskName(tnamebuffer," in NewUnlockPubScreenList()",50);
-
-
- BuggyPSN.psn_Node.ln_Name="Bad LockPubScreenList() Access";
- // 1234567890123456789012345678901234567890
- // 0 0 0 0
- PubListNest--;
-
- if(PubListNest==0)
- {
- while(psn=(struct PubScreenNode *)RemHead(&PubScreenList))
- {
- FreeVec(psn);
- }
- // Add bug alert
- AddHead(&PubScreenList,(struct Node *)(&BuggyPSN));
- }
-
- OldUnlockPubScreenList((struct Library *)IBase);
-
-
- DEBUG_CODE(
- DKP("UnlockPubScreenList()\n");
- )
-
- SetTaskName(tname);
-
- ReleaseSemaphore(&MPSem->NodeSem);
- ReleaseSemaphore(&MPSem->ListSem);
- }
-